/*
 * CollinsAndRoarkTransformApp.java
 *
 * Created on February 26, 2007, 1:23 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package galronnlp.util;

import galronnlp.perceptron.Node;
import java.io.StringReader;
import java.util.Iterator;
import java.util.LinkedList;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
import galronnlp.io.PennTreeReader;
import galronnlp.util.SymbolGenerator;
import galronnlp.util.ContextFreeTreeTransformer;
import galronnlp.util.SimpleUnaryToUnaryRecursionRemover;
import galronnlp.util.ImmediateLeftRecursionLeftCornerTransformer;
import galronnlp.util.SimpleUnaryToUnaryRecursionRemover;

/**
 *
 * @author Dennis N. Mehay
 */
public class CollinsAndRoarkTransformApp {
    public static final int FULL     = -1;
    public static final int SAMPLE   = -2;
    public static final int WSJ      = 2;
    public static final int BROWN    = 3;
    private int sample = FULL;
    private String CorpusRoot = "";
    private int corpus = WSJ;
    private PennTreeReader reader = null;
    private SymbolGenerator gen = null;
    
    /** Creates a new instance of CollinsAndRoarkTransformApp */
    public CollinsAndRoarkTransformApp(String root, int sample, int corpus) {
        this(root, sample, corpus, new SymbolGenerator());
    }
    
    /** Creates a new instance of CollinsAndRoarkTransformApp */
    public CollinsAndRoarkTransformApp(String root, int sample, int corpus, SymbolGenerator gen) {
        if(root.charAt(root.length() - 1) != File.separatorChar) { this.CorpusRoot = root + File.separator; } else { this.CorpusRoot = root; }
        this.sample = sample;
        this.corpus = corpus;
        this.gen = gen;
    }
    
    /** Creates a new instance of CollinsAndRoarkTransformApp */
    public CollinsAndRoarkTransformApp(String root) {
        this(root, FULL, WSJ, new SymbolGenerator());
    }
    
    public void transform() {
        if(corpus == WSJ)
            this.transformWSJ();
        else if(corpus == BROWN)
            System.err.println("NOT YET IMPLEMENTED");
    }
    
    private void transformWSJ() {
        if(sample == this.FULL) this.transformWSJFull();
        else if(sample == this.SAMPLE) this.transformWSJSample();
        else if(sample >= 0) this.transformSection(sample);
    }
    
    private void transformWSJFull() {
        int fileNum = 1;
        int dirNum  = 0;
        CorpusRoot += "parsed"+File.separator+"mrg"+File.separator+"wsj"+File.separator;
        for(dirNum = 0; dirNum < 25; dirNum++) {
            String dirString = "";
            if(dirNum < 10) dirString = "0" + Integer.toString(dirNum);
            else dirString = Integer.toString(dirNum);
            if(dirNum == 0) {
                for(fileNum = 1; fileNum < 100; fileNum++) {
                    String fileString = "";
                    if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
                    else fileString = Integer.toString(fileNum);
                    System.err.println(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                    this.transformWSJTreeFile(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                }
            } else if(dirNum == 3) {
                for(fileNum = 0; fileNum < 81; fileNum++) {
                    String fileString = "";
                    if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
                    else fileString = Integer.toString(fileNum);
                    System.err.println(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                    this.transformWSJTreeFile(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                }
                
            } else if(dirNum == 8) {
                for(fileNum = 0; fileNum < 21; fileNum++) {
                    String fileString = "";
                    if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
                    else fileString = Integer.toString(fileNum);
                    System.err.println(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                    this.transformWSJTreeFile(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                }
                
            } else if(dirNum == 21) {
                for(fileNum = 0; fileNum < 73; fileNum++) {
                    String fileString = "";
                    if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
                    else fileString = Integer.toString(fileNum);
                    System.err.println(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                    this.transformWSJTreeFile(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                }
            } else if(dirNum == 24) {
                for(fileNum = 0; fileNum < 55; fileNum++) {
                    String fileString = "";
                    if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
                    else fileString = Integer.toString(fileNum);
                    System.err.println(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                    this.transformWSJTreeFile(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                }
            } else if(dirNum == 22) {
                for(fileNum = 0; fileNum < 83; fileNum++) {
                    String fileString = "";
                    if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
                    else fileString = Integer.toString(fileNum);
                    System.err.println(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                    this.transformWSJTreeFile(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                }
            } else {
                for(fileNum = 0; fileNum < 100; fileNum++) {
                    String fileString = "";
                    if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
                    else fileString = Integer.toString(fileNum);
                    System.err.println(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                    this.transformWSJTreeFile(CorpusRoot + dirString + File.separator + "wsj_" + dirString + fileString + ".mrg");
                }
            }
        }
    }
    
    private void transformWSJSample() {
        CorpusRoot += "parsed"+File.separator +"mrg"+File.separator+"wsj"+File.separator;
        for(int fileNum = 1; fileNum < 100; fileNum++) {
            String fileString = "";
            if(fileNum < 10) fileString = "0" + Integer.toString(fileNum);
            else fileString = Integer.toString(fileNum);
            System.err.println("wsj_00" + fileString + ".mrg");
            this.transformWSJTreeFile(CorpusRoot + "00" + File.separator + "wsj_" + "00" + fileString + ".mrg");
        }
    }
    
    private void transformSection(int file) {
        // NOT YET FINISHED.  JUST A PROTOTYPE. (D.N.M.)
        String dirString = "", fileString = "", fileExt = ".mrg";
        this.CorpusRoot += "parsed" + File.separator + "mrg" + File.separator + "wsj" + File.separator;
        System.err.println(this.CorpusRoot + "00" + File.separator + "wsj_0001" +fileExt);
        this.transformWSJTreeFile(this.CorpusRoot + "00" + File.separator + "wsj_0001" + fileExt);
    }
    
    private void transformWSJTreeFile(String file) {
        try {
            PennTreeReader reader = new PennTreeReader(new BufferedReader(new FileReader(file)), this.gen);
            ImmediateLeftRecursionLeftCornerTransformer lctr =
                    new ImmediateLeftRecursionLeftCornerTransformer(this.gen);
            ContextFreeTreeTransformer cftr = new ContextFreeTreeTransformer(this.gen);
            SimpleUnaryToUnaryRecursionRemover urtr = new SimpleUnaryToUnaryRecursionRemover(gen);
            Tree t = null;
            String strForest = "", tempCheck1 = null, tempCheck2 = null;;
            int count = 0;
            while(reader.hasNext()) {
                count++;
                t = reader.readTree();
                if(t!=null) {
                    t = urtr.removeUnaryProductions(cftr.contextFreeTransform(t));
                    tempCheck1 = t.toString(false);
                    t = lctr.ILRTransform(t);
                    t = lctr.flatten(t);
                    System.out.println("parseID="+count);
                    System.out.println(t.toString(false));
                    tempCheck2 = lctr.lcReverse(lctr.unflatten(t)).toString(false);
                    if(!tempCheck1.equals(tempCheck2))
                        System.err.println("Failed to verify accuracy of transform for parseID="+file+"-"+count);
                }
            }
            reader.close();
        } catch(Exception e) {
            e.printStackTrace();
        } 
    }
    
    //public String toString() {
    //    String ret = "---------------------------------------\n";
    //    for(Iterator<Tree> i = this.iterator(); i.hasNext(); ) {
    //        ret += i.next().toString(false);
    //        ret += "---------------------------------------\n";
    //    }
    //    return ret;
    //}
    
    public static void main(String[] args) {
        CollinsAndRoarkTransformApp trans = new CollinsAndRoarkTransformApp(args[0], FULL, WSJ);
        trans.transformWSJTreeFile(args[1]);
    }
    
}
